/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.config.mongo;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoDatabase;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.function.Function;

@Slf4j
@Component
public class SecondMongoConnectionManager {

    @Autowired
    private SecondaryMongoProperties mongoProperties;

    /**
     * 执行 MongoDB 操作并自动释放资源
     *
     * @param operation 要执行的 MongoDB 操作
     * @param <T>       返回类型
     * @return 操作结果
     */
    public <T> T executeMongoOperation(Function<MongoClient, T> operation) {
        try (MongoClient mongoClient = createMongoClient()) {
            return operation.apply(mongoClient);
        } catch (Exception e) {
            log.error("Failed to execute MongoDB operation", e);
            throw new RuntimeException("MongoDB operation failed", e);
        }
    }

    private MongoClient createMongoClient() {
        try {
            // 对密码进行编码
            String encodedPassword = URLEncoder.encode(mongoProperties.getPassword(), StandardCharsets.UTF_8);

            // 构建连接字符串
            String connectionString = String.format("mongodb://%s:%s@%s:%d/%s?authSource=%s",
                mongoProperties.getUsername(),
                encodedPassword,
                mongoProperties.getHost(),
                mongoProperties.getPort(),
                mongoProperties.getDatabase(),
                mongoProperties.getAuthenticationDatabase());

            return MongoClients.create(connectionString);
        } catch (Exception e) {
            log.error("Failed to create MongoDB client", e);
            throw new RuntimeException("Failed to create MongoDB client", e);
        }
    }

    public MongoDatabase getDatabase() {
        return executeMongoOperation(client ->
            client.getDatabase(mongoProperties.getDatabase()));
    }

    public MongoDatabase getDatabase(String databaseName) {
        return executeMongoOperation(client ->
            client.getDatabase(databaseName));
    }
}
